﻿using System;
using System.Collections.Generic;
using System.Linq;
using MvcEngine.Mvc.StarterSite.Controllers;
using System.Web.Mvc;
using MvcEngine.Mvc.Models.ViewModels;
using MvcEngine.Core;
using MvcEngine.Mvc.Extensions;
using MvcEngine.Core.Repositories;
using MvcEngine.Core.Helpers;
using System.Web;
using MvcEngine.Mvc.Filters;
using MvcEngine.Core.Exceptions;
using MvcEngine.Core.Configuration;
using MvcEngine.Mvc;
using MvcEngine.Mvc.Models;
using System.IO;
using MvcEngine.Gallery.Components.Extensions;
using MvcEngine.Core.Extensions;
using MvcEngine.Core.Content;
using MvcEngine.Mvc.Controllers;
using MvcEngine.Core.Pagination;
using MvcEngine.Gallery.Managers;
using MvcEngine.Gallery.Models;
using MvcEngine.Core.Localization;
using MvcEngine.Core.Base;


namespace MvcEngine.Gallery.BackOffice.Controllers
{
    public class GalleryImageController : BaseController
    {
        public MvcEngineModel List(Guid galleryId, int? pageNumber)
        {
            if (!pageNumber.HasValue || pageNumber <= 0)
                pageNumber = 1;

            LoadOptions options = IoC.Resolve<LoadOptions>();
            options.PageNumber = pageNumber.Value;
            options.PageSize = 10;

            IPagination<GalleryImage> pagination = GalleryImageManager.Current.GetImagesByGallery(galleryId, options);

            var gallery = GalleryManager.Current.GetGallery(galleryId);
            GalleryImageListPaginationViewModel model = new GalleryImageListPaginationViewModel()
            {
                TotalItems = pagination.TotalItems,
                TotalPages = pagination.TotalPages,
                GalleryName = gallery.Name,
                ViewName = "List",
                Images = new List<GalleryImageDetailsViewModel>(),
                IsCorrectPage = true
            };

            if (pageNumber.Value > pagination.TotalPages && pagination.TotalPages != 0)
            {
                model.IsCorrectPage = false;
            }

            if (pagination.TotalItems == 0)
                return model;

            foreach (var image in pagination)
            {
                var imageViewModel = new GalleryImageDetailsViewModel()
                {
                    Id = image.Id,
                    Categories = GalleryCategoryManager.Current.GetAllByImage(image.Id),
                    Name = image.Name,
                    Description = image.Description,
                    Visible = image.Visible
                };
                model.Images.Add(imageViewModel);
            }

            return model;
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public MvcEngineModel Edit(Guid galleryId, string galleryName, Guid? id)
        {
            GalleryImageEditViewModel model = null;
            if (id.HasValue)
            {
                GalleryImage image = GalleryImageManager.Current.GetImage(id.Value);
                if (image == null)
                    return new MvcEngineModelItem<Guid>() { Item = id.Value, ViewName = "ImageNotFound" };

                var gallery = GalleryManager.Current.GetGallery(galleryId);
                var pageName = ContentManager.Current.GetPage(gallery.PageId).Name;

                model = new GalleryImageEditViewModel()
                {
                    Id = image.Id,
                    Name = image.Name,
                    Url = image.Url,
                    Type = image.Type,
                    PageName = pageName,
                    Visible = image.Visible,
                    Description = image.Description,
                    Categories = GalleryCategoryManager.Current.GetAllByGallery(galleryId),
                    ImageCategories = GalleryCategoryManager.Current.GetAllByImage(image.Id)
                };
            }
            else
            {
                model = new GalleryImageEditViewModel()
                {
                    Type = GalleryImageTypes.Url,
                    Categories = GalleryCategoryManager.Current.GetAllByGallery(galleryId),
                    ImageCategories = new List<GalleryCategory>()
                };
            }
            model.ViewName = "Edit";
            return model;
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [AntiForgeryValidationFilter]
        public ActionResult Delete(string galleryName, Guid id)
        {
            GalleryImageManager.Current.DeleteImage(id);
            return Redirect(Url.Gallery(galleryName));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ActionName("Edit")]
        [ValidateInput(false)]
        [AntiForgeryValidationFilter]
        public object Save(Guid? id, Guid galleryId, GalleryImage image, HttpPostedFileBase file, Dictionary<Guid, bool> categories)
        {
            if (ModelState.IsValid)
            {
                if (!id.HasValue)
                {
                    image.Id = Guid.NewGuid();
                    image.CreatedDate = DateTime.Now;
                }
                else
                {
                    image.Id = id.Value;
                }

                var imageCategories = new List<GalleryImageCategory>();
                if (categories != null)
                {
                    var selectedCategories = categories.Where(c => c.Value).ToList();
                    if (selectedCategories.Count() == 0)
                        return JsonInvalidResource("CategoryRequiredValidator");

                    foreach (var item in categories.Where(c => c.Value))
                    {
                        GalleryImageCategory category = IoC.Resolve<GalleryImageCategory>();
                        category.CategoryId = item.Key;
                        category.Id = Guid.NewGuid();
                        category.ImageId = image.Id;
                        imageCategories.Add(category);
                    }
                }

                if (file != null)
                {
                    string directory = PrepareDirectory(galleryId);
                    string fileName = file.FileName.UrlEncode();
                    string filePath = Path.Combine(directory, fileName);
                    string fileExtension = Path.GetExtension(fileName).Remove(0, 1);
                    if (!FileHelper.Current.Exists(filePath))
                        file.SaveAs(filePath);
                    image.Url = fileName;
                }

                if (string.IsNullOrEmpty(image.Url) && (image.Type != GalleryImageTypes.Physical && id.HasValue))
                {
                    return JsonInvalidResource("UrlOrFileIsRequiredValidator");
                }

                GalleryImageManager.Current.SaveImage(image, imageCategories);

                return JsonValid();
            }
            return JsonInvalid();
        }

        #region Protected methods

        protected virtual string PrepareDirectory(Guid galleryId)
        {
            string directoryPath = ConfigurationUtil.Current.ModulesFolder + Path.DirectorySeparatorChar +
                this.HttpContext.Items["moduleName"].ToString() +
                Path.DirectorySeparatorChar + "Content" + Path.DirectorySeparatorChar + galleryId.ToString();

            DirectoryHelper.Current.CheckFolder(directoryPath);
            return directoryPath;
        }

        #endregion
    }
}
